<script type="text/javascript" src="static/jquery.min.js"></script>
<script type="text/javascript" src="static/jquery.flot.min.js"></script>
<style>
table.txs {
	font-size:75%
}
td.maturity {
	text-align: right;
	white-space: nowrap;
}
td.txid {
	font-family: monospace;
	font-size:7px;
}
td.txid11 {
	font-family: monospace;
	font-size:10px;
}
td.txsize {
	text-align: right;
}
</style>
<div id="light" class="white_content">
<span style="float:right"><img title="Close this popup" class="del" onclick="closepopup()"></span>
<div class="rawdatalabel mono" id="disp_txid"></div>
<pre id="rawdiv"></pre>
<span id="txhexdumpsection" style="width:100%"><div class="rawdatalabel">Raw TX data</div>
<textarea id="txhexdump" style="width:100%" rows="4" readonly onclick="this.select()"></textarea>
</span>
</div><div id="fade" class="black_overlay"></div>
<table width="100%">
<tr>
<td><b>Memory Pool:</b></td>
<td align="right">
<span onclick="mempool_quick_sort.click()" class="hand" title="Uses less bandwidth">
	<input type="checkbox" id="mempool_quick_sort" onchange="show_mempool_fees()" onclick="event.stopPropagation()">Quick
</span>
&nbsp;&bull;&nbsp;
<span onclick="mempool_spb_range.click()" class="hand">
	<input type="checkbox" id="mempool_spb_range" onchange="show_mempool_fees()" onclick="event.stopPropagation()">Limit Y
</span>
&nbsp;&bull;&nbsp;
X for
<span onclick="mempool_siz_range_1.click()" class="hand">
	<input type="radio" name="mempool_siz_range" id="mempool_siz_range_1" onchange="show_mempool_fees()" onclick="event.stopPropagation()">Block
</span>
<span onclick="mempool_siz_range_6.click()" class="hand">
	<input type="radio" name="mempool_siz_range" id="mempool_siz_range_6" onchange="show_mempool_fees()" onclick="event.stopPropagation()" checked>Hour
</span>
<span onclick="mempool_siz_range_a.click()" class="hand">
	<input type="radio" name="mempool_siz_range" id="mempool_siz_range_a" onchange="show_mempool_fees()" onclick="event.stopPropagation()">All
</span>
</td>
</tr>
</table>

<table width="100%">
<tr>
<td colspan="2">
<div id="mempool_fees" style="height:200px;margin:5px"></div>
</tr>


<tr>
<td valign="top">
	<table border="0" width="100%">
		<tr>
			<td>Mempool RAM used:</td>
			<td align="center"><b id="ts_t2s_size_mb"></b> MB / <b id="ts_t2s_cnt"></b> txs</td>
			<td align="center" nowrap="nowrap" style="font-size:70%">avg. <b id="ts_t2s_avg"></b> / tx</td>
		</tr>
		<tr><td>Mempool weight:</td>
			<td align="center"><b id="ts_t2s_weight"></b></td>
			<td align="center" nowrap="nowrap" style="font-size:80%">~ <b id="ts_t2s_blks"></b> blocks</td>
		</tr>
		<tr><td>UTXOs spent in mem:</td>
			<td align="center"><b id="outspent"></b></td>
			<td align="center" nowrap="nowrap" style="font-size:70%">avg. <b id="avg_outsper_tx"></b> / tx</td>
		</tr>
		<tr><td>Rejected transactions:&nbsp;</td>
			<td align="center"><input type="button" id="butre" value="" onclick="show_txsre()"></td>
			<td align="center" nowrap="nowrap">
				<input title="Waiting for inputs" type="button" id="butw4i" value="" onclick="show_txw4i()">
			</td>
		</tr>
		<tr><td>Txs being processed:</td>
			<td align="center">Pend: <b id="ts_ptr1_cnt"></b>
				&nbsp;&bull;&nbsp;
				Net: <b id="ts_ptr2_cnt"></b>
			</td>
			<td align="center" nowrap="nowrap" style="font-size:70%">
				<b id="min_spb"></b> / <b id="cur_fee_spkb" title="Current fee SPKB"></b> SPKB
			</td>
		</tr>
		<tr><td>Fees from 1st block:</td>
			<td align="center"><b id="fees_from_first_block">...</b> BTC</td>
			<td align="center"><input type="button" onclick="show_txs2s('&ownonly=1')" value="Own TXs"></td>
		</tr>
	</table>
<td valign="top">
	<table border="0" cellpadding="0">
	<colset>
		<col width="150">
		<col width="*">
	</colset>
		<tr>
			<td>Memory pool:
			<td><img id="switch_txp_pool" src="static/empty.png" height="32" valign="bottom">
		<tr>
			<td>Relaying transactions:
			<td><img id="switch_txr_pool" src="static/empty.png" height="32" valign="bottom">
		<tr>
			<td colspan="2" class="uploadtx">
				<b>Upload Transaction File:</b><br>
				<br>
				<form id="theform" method="post" enctype="multipart/form-data" onchange="theform.submit()">
					<input name="txfile" type="file">
				</form>
				... or use
				<a href="https://www.blockchain.com/btc/pushtx" target="_blank">blockchain.com</a>
				| <a href="https://blockstream.info/tx/push" target="_blank">blockstream</a>
				| <a href="https://coinb.in/send-raw-transaction.html" target="_blank">coinb.in</a>
				| <a href="https://en.bitcoin.it/wiki/Transaction_broadcasting" target="_blank">more...</a>
				to push it.
	</table>

<tr>
<td colspan="2">
<hr>
Up to
	<select id="mp_show_cnt">
		<option selected>50</option>
		<option>100</option>
		<option>250</option>
		<option>500</option>
		<option>1000</option>
		<option>2000</option>
		<option>5000</option>
		<option>10000</option>
	</select>
mempool txs,
sorted by
	<select id="mp_show_sort">
		<option value="age">age</option>
		<option value="siz">length</option>
		<option value="wgh">weight</option>
		<option value="swc">SegWit compression</option>
		<option value="inp">inputs count</option>
		<option value="out">outputs count</option>
		<option value="btc">BTC volume</option>
		<option value="fee">fee amount</option>
		<option value="ops">sigops count</option>
		<option value="spb" selected>fee per byte</option>
		<option value="rbf">RFB first</option>
		<option value="ver">verify time</option>
	</select>
in descending <input id="mp_show_sort_desc" type="checkbox" checked="checked"> order
- <input type="button" value="show me now..." onclick="show_txs2s('')">
&nbsp;&nbsp;&nbsp;
<input type="button" value="Decode mempool TX" onclick="show_txid()">
<input type="button" value="Decode TX" onclick="show_raw_tx()">
</table>


<!--TX_LOAD-->
</script>
<table class="txs bord" id="txs2s" style="display:none" width="100%">
	<tr>
		<th width="20" align="right">#
		<th width="20" align="right">totlen
		<th>Transaction ID
		<th onclick="sortclick('age')" style="cursor:pointer" width="60" align="right">Maturity
		<th onclick="sortclick('siz')" style="cursor:pointer" width="80" align="right">Len
		<th onclick="sortclick('wgh')" style="cursor:pointer" width="80" align="right">Wght
		<th onclick="sortclick('swc')" style="cursor:pointer" width="80" align="right">SWC
		<th onclick="sortclick('inp')" style="cursor:pointer" width="30" align="right">Inps
		<th onclick="sortclick('out')" style="cursor:pointer" width="30" align="right">Outs
		<th onclick="sortclick('btc')" style="cursor:pointer" width="90" align="right">Total BTC
		<th onclick="sortclick('fee')" style="cursor:pointer" width="80" align="right">Fee BTC
		<th onclick="sortclick('spb')" style="cursor:pointer" width="60" align="right">SPB
		<th onclick="sortclick('ops')" style="cursor:pointer" width="40" align="right">SOps
		<th onclick="sortclick('rbf')" style="cursor:pointer" width="30" align="right" title="Transaction is not final">RBF
		<th onclick="sortclick('ver')" style="cursor:pointer" width="40" align="right" title="Verification time in ms">ms
		<th width="40" align="right">Sent
		<th align="right">Extras
	</tr>
</table>
<table class="txs bord" id="txsre" style="display:none" width="100%">
	<tr>
		<th width="20" align="right">#
		<th>Rejected Transaction ID
		<th onclick="sorttab('txsre', 2)" style="cursor:pointer" width="60" align="right">Maturity
		<th onclick="sorttab('txsre', 3)" style="cursor:pointer" width="60" align="right">Size
		<th width="80" align="right">Sys Size
		<th width="100" align="right">Reason rejected
</table>
<table class="txs bord" id="txw4i" style="display:none" width="100%">
	<tr>
		<th width="20" align="right">#
		<th>Waiting for
		<th>Pending Tx
		<th align="right">Size
		<th onclick="sorttab('txw4i', 4)" style="cursor:pointer" width="60" align="right">Age
</table>
<script>

function sortclick(type) {
	var os = mp_show_sort.options
	if (os[mp_show_sort.selectedIndex].value!=type) {
		mp_show_sort_desc.checked = true
		for (var i=0; i<os.length; i++) {
			if (os[i].value==type) {
				mp_show_sort.selectedIndex = i
				break
			}
		}
	} else {
		mp_show_sort_desc.checked = !mp_show_sort_desc.checked
	}
	show_txs2s('')
}


function enable_pool_switching(el, enable) {
	if (enable) {
		el.addEventListener('click', pool_on_off_click)
		el.style.cursor = 'hand'
		el.title = "Switch ON/OFF"
	} else {
		el.removeEventListener('click', pool_on_off_click)
		el.style.cursor = 'auto'
		el.title = "Switching not possible"
	}
}
enable_pool_switching(switch_txp_pool, !server_mode)
enable_pool_switching(switch_txr_pool, !server_mode)

function set_pool_switch_icon(el, on) {
	el.src = "static/switch-" + (on ? "on" : "off") + ".png"
}

function pool_on_off_click(e) {
	var cmd, el = e.srcElement
	var is_on = el.src.indexOf("switch-on.")!=-1
	console.log(el.id, is_on)
	function on2word(on) {
		return on ? "Disable" : "Enable"
	}

	if (el.id == "switch_txp_pool") {
		if (!confirm(on2word(is_on) + " placing new transactions in mempool?")) return
		cmd = 'txponoff'
	} else if (el.id == "switch_txr_pool") {
		if (!confirm(on2word(is_on) + " routing new transactions to other peers?")) return
		cmd = 'txronoff'
	} else {
		return
	}

	var aj = ajax()
	aj.onerror=function() {
		alert("Error contacting the server")
	}
	aj.onload=function() {
		set_pool_switch_icon(el, aj.responseText==='true')
		enable_pool_switching(el, true)
	}
	enable_pool_switching(el, false)
	aj.open("GET",'cfg?'+cmd+'&sid='+sid, true);
	aj.send(null);
}



function sorter(a,b) {
	return a.val<b.val
}

function sorttab(tid,col) {
	var tbl = document.getElementById(tid).tBodies[0]
	var store = []
	for(var i=0, len=tbl.rows.length; i<len; i++) {
		var row = tbl.rows[i];
		var sortnr = row.cells[col]["numeric_value"]
		if (isNaN(sortnr)) {
			sortnr = parseFloat(row.cells[col].textContent || row.cells[col].innerText);
		}
		if (!isNaN(sortnr)) store.push([sortnr, row]);
	}
	store.sort(function(x,y) {
		return y[0] - x[0];
	});
	for(var i=0, len=store.length; i<len; i++) {
		tbl.appendChild(store[i][1]);
	}
	for (var i=0; i<tbl.rows.length; i++) {
		tbl.rows[i].cells[0].innerHTML = i.toString()
	}
	store = null
}

function get_maturity(t) {
	var secs = parseInt(((new Date()).getTime()/1000) - parseInt(t))
	if (secs<0) secs=0
	if (secs<180)  return secs + ' s'
	var mins = secs / 60
	if (mins>300) return  (mins/60).toFixed(2) + ' h'
	return mins.toFixed(1) + ' min'
}

function send1tx_click(id) {
	if (confirm("Send TX "+id+" to one random peer")) {
		quiet_txs2s('&sendone='+id)
		setTimeout("show_txs2s('&ownonly=1')", 1000)
	}
}

function sendtx_click(id) {
	if (confirm("Broadcast TX "+id)) {
		quiet_txs2s('&send='+id)
		setTimeout("show_txs2s('&ownonly=1')", 1000)
	}
}

function deltx_click(id) {
	if (confirm("Delete TX "+id)) {
		show_txs2s('&del='+id+'&ownonly=1')
	}
	loadedtxdata.innerText = ''
}

var tx_decoding_in_progress = false

function decode_tx() {
	if (!tx_decoding_in_progress) {
		decode_tx_id(this.id)
	}
}

function decode_tx_id(txid) {
	var aj = ajax()
	tx_decoding_in_progress = true
	aj.onreadystatechange=function() {
		if(aj.readyState==4) {
			tx_decoding_in_progress = false

			var sta = xval(aj.responseXML,  "status")
			if (sta!="OK") {
				alert("Error: " + sta)
				return
			}

			disp_txid.innerHTML = xval(aj.responseXML,  "id")

			var tin=0, tout=0, s = ''
			var all_input_values = true

			s += "Version: " + xval(aj.responseXML,  "version") + "\n\n"

			var is = aj.responseXML.getElementsByTagName('input')
			for (var i=0; i<is.length; i++) {
				s += (i+1) + ") " + xval(is[i], "txid-vout") + " "

				var bl = xval(is[i], "block")
				if (isNaN(bl) || bl==0) {
					s += "(unconfirmed)"
				} else {
					s += "(#"+xval(is[i], "block")+")"
				}
				s += " seq=" + parseInt(xval(is[i], "sequence")).toString(16)
				s += " "

				var st = xval(is[i], "status")
				s += "\n  Status : " + st
				var val = parseInt(xval(is[i], "value"))
				if (!isNaN(val)) {
					tin += val
					s += " &bull; "
					s += (parseFloat(val)/1e8).toFixed(8)
					s += " BTC @ "
					var ad = xval(is[i], "addr")
					if (typeof(ad)!="string") {
						s += xval(is[i], "pkscript")
					} else {
						s += ad
					}
				} else all_input_values = false

				var sops = parseInt(xval(is[i], "input_sigops"))
				if (!isNaN(sops)) {
					s += "  + " + sops + ' sigops'
				}
				var inspcr = xval(is[i], "script_sig")
				if (typeof(inspcr)=="string") {
					s += "\n  SigScript length " +inspcr.length/2 + ":"
					for (var k=0; k<inspcr.length; k+=140) {
						s += "\n    " + inspcr.substr(k, 140)
					}
				}

				var segwit = is[i].getElementsByTagName("witness")
				if (segwit.length>0) {
					s += "\n  SegWit stack:"
					for (var k=0; k<segwit.length; k++) {
						if (segwit[k].childNodes.length>0) {
							s += "\n    " + segwit[k].childNodes[0].nodeValue
						} else {
							s += "\n    OP_0"
						}
					}
				}

				s += "\n\n"
			}
			s += "Total input: " + (parseFloat(tin)/1e8).toFixed(8) + " BTC\n"
			s += "\n"

			is = aj.responseXML.getElementsByTagName('output')
			for (var i=0; i<is.length; i++) {
				s += (i+1) + ") "
				var val = parseInt(xval(is[i], "value"))
				tout += val
				s += (parseFloat(val)/1e8).toFixed(8)
				s += " BTC => " + xval(is[i], "addr")
				s += "\n"
			}
			s += "Total output: " + (parseFloat(tout)/1e8).toFixed(8) + " BTC\n"
			s += "\n"
			s += "Lock time: " + xval(aj.responseXML,  "lock_time") + "\n\n"
			var fee = tin-tout

			var sw_compr =  + '%'

			var size = parseInt(xval(aj.responseXML,  "size"))
			var nwsize = parseInt(xval(aj.responseXML,  "nwsize"))
			var weight = parseInt(xval(aj.responseXML,  "weight"))
			var vsize = (size==nwsize) ? size : ((3*(nwsize+1) + size) >> 2)
			s += 'TxSize: ' + size
            s += '  /  NoWit:' + nwsize
            s += ' (' + (xval(aj.responseXML, "sw_compress") / 10.0).toFixed(1) + '%)'
			s += '  /  Weight: ' + weight
            s += '  /  VSize:' + vsize
			s += '  /  Sigops: ' + xval(aj.responseXML,  "sigops") + '\n'

			if (all_input_values) {
				s += "Fee: " + (parseFloat(fee)/1e8).toFixed(8) + " BTC"
				s += '  ==> ' + parseFloat(fee/vsize).toFixed(5) + ' Satoshis per byte\n'
			}

			s += 'Verification took: ' + xval(aj.responseXML,  "verify_us") + ' microseconds\n'

			rawdiv.innerHTML = s

			txhexdump.value = xval(aj.responseXML,  "raw")

			if (prvpos==null) {
				fade.addEventListener('click', closepopup)
				fade.style.cursor = 'pointer'
				fade.title = 'Click here to close the popup'
			}


			prvpos = document.body.scrollTop
			window.scrollTo(0,0)

			txhexdumpsection.style.display = 'inline'
			light.style.display='block'
			fade.style.display='block'
			document.addEventListener("scroll", noscroll)
		}
	}
	aj.open("GET","txs2s.xml?id="+txid, true);
	aj.send(null);
}

function do_raw_tx(txid) {
	var aj = ajax()
	tx_decoding_in_progress = true
	aj.onreadystatechange=function() {
		if(aj.readyState==4) {
			tx_decoding_in_progress = false
			disp_txid.innerText = txid
			rawdiv.innerHTML = aj.responseText
			prvpos = document.body.scrollTop
			window.scrollTo(0,0)
			txhexdumpsection.style.display = 'none'
			light.style.display='block'
			fade.style.display='block'
			document.addEventListener("scroll", noscroll)
		}
	}
	aj.open("GET","raw_tx?id="+txid, true);
	aj.send(null);
}

// same as decode_tx, but will also do rejected tx
function decode_tx2() {
	if (!tx_decoding_in_progress) {
		do_raw_tx(this.id)
	}
}

function show_raw_tx() {
	if (!tx_decoding_in_progress) {
		var tid = prompt("Enter ID of the TX");
		if (tid!=null) {
			do_raw_tx(tid)
		}
	}
}

function quiet_txs2s(extrapar) {
	var aj = ajax()
	aj.open("GET","txs2s.xml?quiet=1&sid="+sid+extrapar, true);
	aj.send(null);
}

function show_txs2s(extrapar) {
	var aj = ajax()
	aj.onreadystatechange=function() {
		if(aj.readyState==4) {
			while (txs2s.rows.length>1)  txs2s.deleteRow(1)
			txs = aj.responseXML.getElementsByTagName('tx')
			var lensofar = 0
			for (var i=0; i<txs.length; i++) {
				var c,row
				var own = xval(txs[i], 'own')==='true'
				var txid = xval(txs[i], 'id')

				row = txs2s.insertRow(-1)
				row.className='hov'

				var len = parseInt(xval(txs[i], 'size'))
				lensofar += len

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = (i+1).toString()

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = lensofar

				c = row.insertCell(-1)
				c.className ='txid'
				c.innerHTML = txid
				c.id = txid
				c.addEventListener('click', decode_tx, false)
				c.style.cursor='pointer'

				c=row.insertCell(-1);c.className='maturity'
				var tim = xval(txs[i], 'time')
				c["numeric_value"]  = tim
				c.innerHTML = get_maturity(tim)

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = len
				var nws = 'No witness size:' + xval(txs[i], 'nwsize')
				c.title = nws

				c=row.insertCell(-1);c.align='right'
				var weight = xval(txs[i], 'weight')
				c.innerHTML += weight
				c.title = 'Virtual size:' + (weight/4).toFixed(0)

				c=row.insertCell(-1);c.align='right'
				c.innerHTML += (xval(txs[i], 'sw_compress') / 10.0).toFixed(0) + '%'
				c.title = nws

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = xval(txs[i], 'inputs')
				var mic = xval(txs[i], 'meminputcnt')
				if (mic>0) {
					c.innerHTML = '<sup style="font-size:75%">'+mic+'</sup> ' + c.innerHTML
					c.title = mic + " unconfired input" + (mic>1 ? "s" : "")
				}

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = xval(txs[i], 'outputs')


				c=row.insertCell(-1);c.align='right'
				c.innerHTML = (parseFloat(xval(txs[i], 'volume'))/1e8).toFixed(8)

				var fee = parseFloat(xval(txs[i], 'fee'))

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = (fee/1e8).toFixed(8)

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = (parseFloat(fee)/(parseFloat(xval(txs[i], 'weight'))/4)).toFixed(1)

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = xval(txs[i], 'sigops')

				c=row.insertCell(-1);c.align='center'
				if (xval(txs[i], 'final')!='true') c.innerHTML = '*'

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = (xval(txs[i], 'verify_us')/1e3).toFixed(1)

				c=row.insertCell(-1);c.align='right'
				var sc = xval(txs[i], 'sentcnt')
				c.innerHTML = sc + "/" + xval(txs[i], 'invsentcnt')
				if (sc>0) {
					var tim = new Date(xval(txs[i], 'sentlast')*1000)
					c.title = "Last sent at "+tim.getHours()+":"+leftpad(tim.getMinutes(),'0',2)+":"+leftpad(tim.getSeconds(),'0',2)
				}

				c=row.insertCell(-1);c.align='right'
				if (own) {
                    c.innerHTML = '<img style="cursor:pointer" title="Send this TX to one random peer" onclick="send1tx_click(\''+txid+'\')" src="static/send_once.png">'
					c.innerHTML += '&nbsp;'
                    c.innerHTML += '<img style="cursor:pointer" title="Broadcast this TX" onclick="sendtx_click(\''+txid+'\')" src="static/send.png">'
					c.innerHTML += '&nbsp;'
                    c.innerHTML += '<img title="Remove this TX" onclick="deltx_click(\''+txid+'\')" class="del">'
				} else {
					c.innerHTML = xval(txs[i], 'blocked')
				}

				if (own) {
					row.classList.add('own')
					row.title = 'Your own transaction'
				}

				if (xval(txs[i], 'witness_cnt') > 0) {
					row.classList.add('segwit')
					row.title = 'Segregated Witness transaction'
				}
			}
			txs2s.style.display = 'table'
		}
	}
	txs2s.style.display = txsre.style.display = txw4i.style.display = 'none'

	extrapar += '&cnt='+mp_show_cnt.options[mp_show_cnt.selectedIndex].value
	extrapar += '&sort='+mp_show_sort.options[mp_show_sort.selectedIndex].value
	if (mp_show_sort_desc.checked) {
		extrapar += '&descending'
	}
	aj.open("GET","txs2s.xml?sid="+sid+extrapar, true);
	aj.send(null);
}


function show_txsre() {
	var aj = ajax()
	aj.onreadystatechange=function() {
		if(aj.readyState==4) {
			while (txsre.rows.length>1)  txsre.deleteRow(1)
			txs = aj.responseXML.getElementsByTagName('tx')
			for (var i=0; i<txs.length; i++) {
				var row = txsre.insertRow(-1)
				var inmem = xval(txs[i], 'inmem')==='true'

				row.className='hov'

				var c = row.insertCell(-1);c.align='right'
				c.innerHTML = (i+1).toString()

				c = row.insertCell(-1)
				c.className ='txid11'
				add_txid_and_icon(c, xval(txs[i], 'id'), inmem)

				c=row.insertCell(-1);className='maturity'
				var tim = xval(txs[i], 'time')
				c["numeric_value"]  = tim
				c.innerHTML = get_maturity(tim)

				c=row.insertCell(-1);c.align='right'
				if (inmem) {
					c.innerHTML = '<b>'+xval(txs[i], 'size')+'</b>'
				} else {
					c.innerHTML = '<i style="font-size:75%">'+xval(txs[i], 'size')+'</i>'
				}

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = '<b>'+xval(txs[i], 'syssize')+'</b>'

				c=row.insertCell(-1);c.align='right'
				c.innerHTML = xval(txs[i], 'reason')
			}
			txsre.style.display = 'table'
		}
	}
	txs2s.style.display = txsre.style.display = txw4i.style.display = 'none'
	aj.open("GET","txsre.xml", true);
	aj.send(null);
}

function show_txw4i() {
	var aj = ajax()
	aj.onreadystatechange=function() {
		if(aj.readyState==4) {
			while (txw4i.rows.length>1)  txw4i.deleteRow(1)
			wait4s = aj.responseXML.getElementsByTagName('wait4')
			var idx=0
			//butw4i.value = ' ' + wait4s.length + ' '
			for (var i=0; i<wait4s.length; i++) {
				pendtxs = wait4s[i].getElementsByTagName('tx')
				idx++
				for (var j=0; j<pendtxs.length; j++) {
					var row = txw4i.insertRow(-1)

					row.className='hov'

					var c = row.insertCell(-1);c.align='right'
					if (j==0) {
						c.innerHTML = idx.toString()
					}

					c = row.insertCell(-1)
					c.className ='txid11'
					add_txid_and_icon(c, xval(wait4s[i], 'id'), false)

					c = row.insertCell(-1)
					c.className ='txid11'
					add_txid_and_icon(c, xval(pendtxs[j], 'id'), true)

					c = row.insertCell(-1)
					c.className = 'txsize'
					c.innerText = xval(pendtxs[j], 'size')

					c = row.insertCell(-1)
					c.className='maturity'
					var tim = xval(pendtxs[j], 'time')
					c["numeric_value"]  = tim
					c.innerHTML = get_maturity(tim)
				}
			}
			txw4i.style.display = 'table'
		}
	}
	txs2s.style.display = txsre.style.display = txw4i.style.display = 'none'
	aj.open("GET","txw4i.xml", true);
	aj.send(null);
}

function add_txid_and_icon(td, txid, decode) {
	var txt
	if (decode) {
		txt = document.createElement("span")
		txt.innerHTML = txid
		txt.title = 'Decode this Tx'
		txt.id = txid
		txt.addEventListener('click', decode_tx2, false)
		txt.style.cursor='pointer'
	} else {
		txt = document.createElement("a")
		txt.innerHTML = txid
		txt.href = 'https://mempool.space/tx/'+txid
		txt.title = 'Look at mempool.space'
		txt.target = '_blank'
	}
	td.appendChild(txt)

	td.appendChild(document.createTextNode('\u00A0'))

	// add copy icon
	var img = document.createElement("img")
	img["text2copy"] = txid
	img.style.verticalAlign = "bottom"
	img.src = "static/copy.png"
	img.className = "hand"
	img.title = "Copy TxID to clipboard"
	img.addEventListener("click", copyonclick)
	td.appendChild(img)
}


var previousPoint = null
var mp = []
var first_run = true
var loading_in_progress = false

function showTooltip(x, y, contents) {
	$('<div id="tooltip">' + contents + '</div>').css( {
		position: 'absolute',
		display: 'none',
		top: y - 30,
		left: x + 5,
		border: '2px solid #fdd',
		padding: '5px',
		'font-size' : '14px',
		'background-color': dark_mode ? '#111111' : '#fee',
		opacity: 1
	}).appendTo("body").fadeIn(200);
}

function time2str(sec) {
	if (sec < 3600) {
		return (sec/60).toFixed(1) + ' min'
	}
	if (sec < 24*3600) {
		return (sec/3600).toFixed(1) + ' hour'
	}
	return (sec/(24*3600)).toFixed(1) + ' day'
}

function handlehover(event, pos, item) {
	if (item) {
		if (previousPoint != item.dataIndex) {
			previousPoint = item.dataIndex;
			$("#tooltip").remove();

			if (loading_in_progress) return

			var rec = mp[item.dataIndex]

			var str = ''
			if (typeof(rec.Current_tx_spb)!="number") {
				str += (rec[1]/1000).toFixed(2) + ' SPB'
				str += ' @ ' + (rec[0]/4e6).toFixed(2) + 'BL'
			} else {

				str += 'Tx #'+(rec.Txs_so_far+1) + ' (' + (rec.Txs_cnt_here) + ') - '
				str += rec.Current_tx_spb.toFixed(2) + ' SPB<br>'
				str += parseInt(rec.Current_tx_weight/4) + ' bytes'
				str += ', ' + time2str(parseInt(new Date().getTime())/1000 - rec.Time_received) +' old<br>'
				str += '' + (rec.Weight_so_far/1e6).toFixed(2) + ' MW'
				str += ' &#8594; ' + (rec.Weight_so_far/4e6).toFixed(2) + ' Blocks<br>'
				str += ' Fees: ' + val2str(rec.Fees_so_far) + ' BTC<br>'
				str += ' Ord: ' + (100*rec.Ord_weight_so_far/rec.Weight_so_far).toFixed(0) + '% weight<br>'
				str += ' &nbsp;&nbsp;&nbsp;' + val2str(rec.Ord_fees_so_far) + ' BTC<br>'
			}
			showTooltip(item.pageX, item.pageY, str)
		}
	} else {
		$("#tooltip").remove();
		previousPoint = null;
	}
}

function handleclick(event, pos, item) {
	if (!loading_in_progress && !mempool_quick_sort.checked && !tx_decoding_in_progress) {
		var rec = mp[item.dataIndex]
		decode_tx_id(rec.Current_tx_id)
	}
}

function show_txid() {
	if (!tx_decoding_in_progress) {
		var tid = prompt("Enter ID of the TX");
		if (tid!=null) {
			decode_tx_id(tid)
		}
	}
}

function show_mempool_fees() {
	var aj = ajax()
	var one_block = mempool_siz_range_1.checked
	var quick_mode = mempool_quick_sort.checked

	loading_in_progress = true

	aj.onreadystatechange=function() {
		if(aj.readyState==4) {
			mp = JSON.parse(aj.responseText)
			if (mp==null) return

			var col1 = "#e0ffe0"
			var col2 = "#f0f0e0"
			var col3 = "#ffe0e0"
			if (dark_mode) {
				col1 = "#112211"
				col2 = "#222211"
				col3 = "#332211"
			}

			//console.log(mp.length, mp[0], mp[1])
			var plot_data = [ { data : [], color : '#9440ED', points: { show:!one_block, fillColor:flot_points_fill_color() }, lines: {show:true, fill:true}} ];
			var plot_options = {
				grid: {
					markings: [ { xaxis: { from: 0, to: 4e6 }, color: col1 },
						{ xaxis: { from: 4e6, to: 8e6 }, color: col2 },
						{ xaxis: { from: 8e6 }, color: col3 },
					 ],
					hoverable: true,
					clickable: true
				},
				xaxis: {
					//tickLength : 1e6,
					minTickSize : one_block ? 4e5 : 4e6,
					tickFormatter : function(a,b) {return (a/4e6).toFixed(1)}
				},
				yaxis : {
					//position : "left"
				}
			}

			var max_spb = 0
			var max_spb_corrected = 0
			var feesfrom1stblock = 0
			var lenforfee = 0
			var cur_wght, cur_spb, fees_sofar, lowest_seen_spb = 21e14

			for (var i=0; i < mp.length; i++) {
				if (quick_mode) {
					cur_wght = mp[i][0]
					cur_spb = (mp[i][1])/1000
					fees_sofar = mp[i][2]
				} else {
					cur_wght = mp[i].Weight_so_far
					cur_spb = mp[i].Current_tx_spb
					fees_sofar = mp[i].Fees_so_far
				}
				if (cur_spb > max_spb) {
					max_spb = cur_spb
				}
				if (cur_wght < 4e6) {
					feesfrom1stblock = fees_sofar
					lenforfee = cur_wght
				}

				// do not let spb to go down in the chart as then it will look weird
				if (cur_spb > lowest_seen_spb) {
					cur_spb = lowest_seen_spb
				} else {
					lowest_seen_spb = cur_spb
				}
				plot_data[0].data.push([cur_wght, cur_spb])
			}
			max_spb_corrected = 20*(feesfrom1stblock/lenforfee)
			if (mempool_spb_range.checked && max_spb > max_spb_corrected) {
				plot_options.yaxis.max = max_spb_corrected
			}

			if (first_run) {
				$("#mempool_fees").bind("plothover", handlehover)
				$("#mempool_fees").bind("plotclick", handleclick)
				first_run = false
			}
			$.plot($("#mempool_fees"), plot_data, plot_options)

			fees_from_first_block.innerText = (feesfrom1stblock/1e8).toFixed(4)
			loading_in_progress = false
		}
	}

	var params = ''
	function add2param(s) {
		if (params == '') {
			params = '?'+s
		} else {
			params += '&'+s
		}
	}

	if (!quick_mode) add2param('full')

	localStorage.setItem("txs_chart_y_limit", mempool_spb_range.checked)
	localStorage.setItem("txs_chart_new_sort", mempool_quick_sort.checked)

	if (mempool_siz_range_1.checked) {
		localStorage.setItem("txs_chart_x", "1")
		add2param('max=4000000&div=1')
	} else if (mempool_siz_range_6.checked) {
		localStorage.setItem("txs_chart_x", "6")
		add2param('max=24000000')
	} else {
		localStorage.setItem("txs_chart_x", "a")
	}
	aj.open("GET", "mpfees.json"+params, true)
	aj.send(null)
}



function refreshtxstat() {
	var aj = ajax()
	aj.onerror=function() {
		setTimeout(refreshtxstat, 5000)
	}
	aj.onload=function() {
		try {
			var ts = JSON.parse(aj.responseText)

			ts_t2s_size_mb.innerText = (ts.t2s_size/1e6).toFixed(1)
			ts_t2s_cnt.innerText = ts.t2s_cnt
			ts_t2s_weight.innerText = ts.t2s_weight.toLocaleString()

			ts_t2s_blks.innerText = (ts.t2s_weight/4e6).toFixed(2)
			ts_t2s_avg.innerText = (ts.t2s_size/ts.t2s_cnt).toFixed(0)
			outspent.innerText = ts.spent_outs_cnt.toLocaleString()
			if (ts.t2s_cnt>0) {
				avg_outsper_tx.innerText = (ts.spent_outs_cnt/ts.t2s_cnt).toFixed(2)
			} else {
				avg_outsper_tx.innerText = '?'
			}
			butre.value = (ts.tre_size/1e3).toFixed(1)+' KB in ' + ts.tre_cnt + ' txs'
			butw4i.value = ts.awaiting_inputs + " / " + (ts.awaiting_inputs_size/1e3).toFixed(1) + " KB"
			ts_ptr1_cnt.innerText = ts.ptr1_cnt
			ts_ptr2_cnt.innerText = ts.ptr2_cnt
			min_spb.innerText = ts.min_fee_per_kb

			cur_fee_spkb.innerText = ts.current_fee_adjusted_spkb

			set_pool_switch_icon(switch_txp_pool, ts.tx_pool_on)
			set_pool_switch_icon(switch_txr_pool, ts.tx_routing_on)
		} catch(e) {
			console.log(e)
		}
		setTimeout(refreshtxstat, 1000)
	}
	aj.open("GET","txstat.json",true)
	aj.send(null)
}

function restore_settings() {
	var el = document.getElementById('mempool_siz_range_'+localStorage.getItem("txs_chart_x"))
	if (el!=null) el.checked = true
	mempool_spb_range.checked = localStorage.getItem("txs_chart_y_limit") !== "false"
	mempool_quick_sort.checked = localStorage.getItem("txs_chart_new_sort") !== "false"
}
restore_settings()

document.addEventListener('DOMContentLoaded', function() {
	refreshtxstat()
	window.onkeyup = function (event) {
		if(event.keyCode == 27)  closepopup()
	}
})

blno.addEventListener("lastblock", function(e) {
	show_mempool_fees()
})

dark_light_icon.addEventListener("theme_changed", function(e) {
	show_mempool_fees()
})

</script>
